home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / lib / firefox-3.5.5 / components / FeedConverter.js < prev    next >
Text File  |  2009-11-09  |  26KB  |  775 lines

  1. //@line 39 "/build/buildd/firefox-3.5-3.5.5+nobinonly/build-tree/mozilla/browser/components/feeds/src/FeedConverter.js"
  2.  
  3. const Cc = Components.classes;
  4. const Ci = Components.interfaces;
  5. const Cr = Components.results;
  6.  
  7. function LOG(str) {
  8.   dump("*** " + str + "\n");
  9. }
  10.  
  11. const FC_CLASSID = Components.ID("{229fa115-9412-4d32-baf3-2fc407f76fb1}");
  12. const FC_CLASSNAME = "Feed Stream Converter";
  13. const FS_CLASSID = Components.ID("{2376201c-bbc6-472f-9b62-7548040a61c6}");
  14. const FS_CLASSNAME = "Feed Result Service";
  15. const FS_CONTRACTID = "@mozilla.org/browser/feeds/result-service;1";
  16. const FPH_CONTRACTID = "@mozilla.org/network/protocol;1?name=feed";
  17. const FPH_CLASSID = Components.ID("{4f91ef2e-57ba-472e-ab7a-b4999e42d6c0}");
  18. const FPH_CLASSNAME = "Feed Protocol Handler";
  19. const PCPH_CONTRACTID = "@mozilla.org/network/protocol;1?name=pcast";
  20. const PCPH_CLASSID = Components.ID("{1c31ed79-accd-4b94-b517-06e0c81999d5}");
  21. const PCPH_CLASSNAME = "Podcast Protocol Handler";
  22.  
  23. const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
  24. const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
  25. const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
  26. const TYPE_ANY = "*/*";
  27.  
  28. const FEEDHANDLER_URI = "about:feeds";
  29.  
  30. const PREF_SELECTED_APP = "browser.feeds.handlers.application";
  31. const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
  32. const PREF_SELECTED_ACTION = "browser.feeds.handler";
  33. const PREF_SELECTED_READER = "browser.feeds.handler.default";
  34.  
  35. const PREF_VIDEO_SELECTED_APP = "browser.videoFeeds.handlers.application";
  36. const PREF_VIDEO_SELECTED_WEB = "browser.videoFeeds.handlers.webservice";
  37. const PREF_VIDEO_SELECTED_ACTION = "browser.videoFeeds.handler";
  38. const PREF_VIDEO_SELECTED_READER = "browser.videoFeeds.handler.default";
  39.  
  40. const PREF_AUDIO_SELECTED_APP = "browser.audioFeeds.handlers.application";
  41. const PREF_AUDIO_SELECTED_WEB = "browser.audioFeeds.handlers.webservice";
  42. const PREF_AUDIO_SELECTED_ACTION = "browser.audioFeeds.handler";
  43. const PREF_AUDIO_SELECTED_READER = "browser.audioFeeds.handler.default";
  44.  
  45. function getPrefAppForType(t) {
  46.   switch (t) {
  47.     case Ci.nsIFeed.TYPE_VIDEO:
  48.       return PREF_VIDEO_SELECTED_APP;
  49.  
  50.     case Ci.nsIFeed.TYPE_AUDIO:
  51.       return PREF_AUDIO_SELECTED_APP;
  52.  
  53.     default:
  54.       return PREF_SELECTED_APP;
  55.   }
  56. }
  57.  
  58. function getPrefWebForType(t) {
  59.   switch (t) {
  60.     case Ci.nsIFeed.TYPE_VIDEO:
  61.       return PREF_VIDEO_SELECTED_WEB;
  62.  
  63.     case Ci.nsIFeed.TYPE_AUDIO:
  64.       return PREF_AUDIO_SELECTED_WEB;
  65.  
  66.     default:
  67.       return PREF_SELECTED_WEB;
  68.   }
  69. }
  70.  
  71. function getPrefActionForType(t) {
  72.   switch (t) {
  73.     case Ci.nsIFeed.TYPE_VIDEO:
  74.       return PREF_VIDEO_SELECTED_ACTION;
  75.  
  76.     case Ci.nsIFeed.TYPE_AUDIO:
  77.       return PREF_AUDIO_SELECTED_ACTION;
  78.  
  79.     default:
  80.       return PREF_SELECTED_ACTION;
  81.   }
  82. }
  83.  
  84. function getPrefReaderForType(t) {
  85.   switch (t) {
  86.     case Ci.nsIFeed.TYPE_VIDEO:
  87.       return PREF_VIDEO_SELECTED_READER;
  88.  
  89.     case Ci.nsIFeed.TYPE_AUDIO:
  90.       return PREF_AUDIO_SELECTED_READER;
  91.  
  92.     default:
  93.       return PREF_SELECTED_READER;
  94.   }
  95. }
  96.  
  97. function safeGetCharPref(pref, defaultValue) {
  98.   var prefs =   
  99.       Cc["@mozilla.org/preferences-service;1"].
  100.       getService(Ci.nsIPrefBranch);
  101.   try {
  102.     return prefs.getCharPref(pref);
  103.   }
  104.   catch (e) {
  105.   }
  106.   return defaultValue;
  107. }
  108.  
  109. function FeedConverter() {
  110. }
  111. FeedConverter.prototype = {
  112.   /**
  113.    * This is the downloaded text data for the feed.
  114.    */
  115.   _data: null,
  116.   
  117.   /**
  118.    * This is the object listening to the conversion, which is ultimately the
  119.    * docshell for the load.
  120.    */
  121.   _listener: null,
  122.  
  123.   /**
  124.    * Records if the feed was sniffed
  125.    */
  126.   _sniffed: false,
  127.   
  128.   /**
  129.    * See nsIStreamConverter.idl
  130.    */
  131.   canConvert: function FC_canConvert(sourceType, destinationType) {
  132.     // We only support one conversion.
  133.     return destinationType == TYPE_ANY && ((sourceType == TYPE_MAYBE_FEED) ||
  134.                                            (sourceType == TYPE_MAYBE_VIDEO) ||
  135.                                            (sourceType == TYPE_MAYBE_AUDIO));
  136.   },
  137.   
  138.   /**
  139.    * See nsIStreamConverter.idl
  140.    */
  141.   convert: function FC_convert(sourceStream, sourceType, destinationType, 
  142.                                context) {
  143.     throw Cr.NS_ERROR_NOT_IMPLEMENTED;
  144.   },
  145.   
  146.   /**
  147.    * See nsIStreamConverter.idl
  148.    */
  149.   asyncConvertData: function FC_asyncConvertData(sourceType, destinationType,
  150.                                                  listener, context) {
  151.     this._listener = listener;
  152.   },
  153.   
  154.   /**
  155.    * Whether or not the preview page is being forced.
  156.    */
  157.   _forcePreviewPage: false,
  158.   
  159.   /** 
  160.    * Release our references to various things once we're done using them.
  161.    */
  162.   _releaseHandles: function FC__releaseHandles() {
  163.     this._listener = null;
  164.     this._request = null;
  165.     this._processor = null;
  166.   },
  167.   
  168.   /**
  169.    * See nsIFeedResultListener.idl
  170.    */
  171.   handleResult: function FC_handleResult(result) {
  172.     // Feeds come in various content types, which our feed sniffer coerces to
  173.     // the maybe.feed type. However, feeds are used as a transport for 
  174.     // different data types, e.g. news/blogs (traditional feed), video/audio
  175.     // (podcasts) and photos (photocasts, photostreams). Each of these is 
  176.     // different in that there's a different class of application suitable for
  177.     // handling feeds of that type, but without a content-type differentiation
  178.     // it is difficult for us to disambiguate.
  179.     // 
  180.     // The other problem is that if the user specifies an auto-action handler
  181.     // for one feed application, the fact that the content type is shared means 
  182.     // that all other applications will auto-load with that handler too, 
  183.     // regardless of the content-type. 
  184.     //
  185.     // This means that content-type alone is not enough to determine whether
  186.     // or not a feed should be auto-handled. This means that for feeds we need
  187.     // to always use this stream converter, even when an auto-action is 
  188.     // specified, not the basic one provided by WebContentConverter. This 
  189.     // converter needs to consume all of the data and parse it, and based on
  190.     // that determination make a judgement about type. 
  191.     //
  192.     // Since there are no content types for this content, and I'm not going to
  193.     // invent any, the upshot is that while a user can set an auto-handler for
  194.     // generic feed content, the system will prevent them from setting an auto-
  195.     // handler for other stream types. In those cases, the user will always see
  196.     // the preview page and have to select a handler. We can guess and show 
  197.     // a client handler, but will not be able to show web handlers for those
  198.     // types.
  199.     //
  200.     // If this is just a feed, not some kind of specialized application, then
  201.     // auto-handlers can be set and we should obey them. 
  202.     try {
  203.       var feedService = 
  204.           Cc["@mozilla.org/browser/feeds/result-service;1"].
  205.           getService(Ci.nsIFeedResultService);
  206.       if (!this._forcePreviewPage && result.doc) {
  207.         var feed = result.doc.QueryInterface(Ci.nsIFeed);
  208.         var handler = safeGetCharPref(getPrefActionForType(feed.type), "ask");
  209.  
  210.         if (handler != "ask") {
  211.           if (handler == "reader")
  212.             handler = safeGetCharPref(getPrefReaderForType(feed.type), "bookmarks");
  213.           switch (handler) {
  214.             case "web":
  215.               var wccr = 
  216.                   Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
  217.                   getService(Ci.nsIWebContentConverterService);
  218.               if ((feed.type == Ci.nsIFeed.TYPE_FEED &&
  219.                    wccr.getAutoHandler(TYPE_MAYBE_FEED)) ||
  220.                   (feed.type == Ci.nsIFeed.TYPE_VIDEO &&
  221.                    wccr.getAutoHandler(TYPE_MAYBE_VIDEO_FEED)) ||
  222.                   (feed.type == Ci.nsIFeed.TYPE_AUDIO &&
  223.                    wccr.getAutoHandler(TYPE_MAYBE_AUDIO_FEED))) {
  224.                 wccr.loadPreferredHandler(this._request);
  225.                 return;
  226.               }
  227.               break;
  228.  
  229.             default:
  230.               LOG("unexpected handler: " + handler);
  231.               // fall through -- let feed service handle error
  232.             case "bookmarks":
  233.             case "client":
  234.               try {
  235.                 var title = feed.title ? feed.title.plainText() : "";
  236.                 var desc = feed.subtitle ? feed.subtitle.plainText() : "";
  237.                 feedService.addToClientReader(result.uri.spec, title, desc, feed.type);
  238.                 return;
  239.               } catch(ex) { /* fallback to preview mode */ }
  240.           }
  241.         }
  242.       }
  243.           
  244.       var ios = 
  245.           Cc["@mozilla.org/network/io-service;1"].
  246.           getService(Ci.nsIIOService);
  247.       var chromeChannel;
  248.  
  249.       // show the feed page if it wasn't sniffed and we have a document,
  250.       // or we have a document, title, and link or id
  251.       if (result.doc && (!this._sniffed ||
  252.           (result.doc.title && (result.doc.link || result.doc.id)))) {
  253.  
  254.         // If there was no automatic handler, or this was a podcast,
  255.         // photostream or some other kind of application, we must always
  256.         // show the preview page.
  257.         
  258.         // Store the result in the result service so that the display
  259.         // page can access it.
  260.  
  261.         feedService.addFeedResult(result);
  262.  
  263.         // Now load the actual XUL document.
  264.         var chromeURI = ios.newURI(FEEDHANDLER_URI, null, null);
  265.         chromeChannel = ios.newChannelFromURI(chromeURI, null);
  266.         chromeChannel.originalURI = result.uri;
  267.       }
  268.       else
  269.         chromeChannel = ios.newChannelFromURI(result.uri, null);
  270.  
  271.       chromeChannel.loadGroup = this._request.loadGroup;
  272.       chromeChannel.asyncOpen(this._listener, null);
  273.     }
  274.     finally {
  275.       this._releaseHandles();
  276.     }
  277.   },
  278.   
  279.   /**
  280.    * See nsIStreamListener.idl
  281.    */
  282.   onDataAvailable: function FC_onDataAvailable(request, context, inputStream, 
  283.                                                sourceOffset, count) {
  284.     if (this._processor)
  285.       this._processor.onDataAvailable(request, context, inputStream,
  286.                                       sourceOffset, count);
  287.   },
  288.   
  289.   /**
  290.    * See nsIRequestObserver.idl
  291.    */
  292.   onStartRequest: function FC_onStartRequest(request, context) {
  293.     var channel = request.QueryInterface(Ci.nsIChannel);
  294.  
  295.     // Check for a header that tells us there was no sniffing
  296.     // The value doesn't matter.
  297.     try {
  298.       var httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
  299.       var noSniff = httpChannel.getResponseHeader("X-Moz-Is-Feed");
  300.     }
  301.     catch (ex) {
  302.       this._sniffed = true;
  303.     }
  304.  
  305.     this._request = request;
  306.     
  307.     // Save and reset the forced state bit early, in case there's some kind of
  308.     // error.
  309.     var feedService = 
  310.         Cc["@mozilla.org/browser/feeds/result-service;1"].
  311.         getService(Ci.nsIFeedResultService);
  312.     this._forcePreviewPage = feedService.forcePreviewPage;
  313.     feedService.forcePreviewPage = false;
  314.  
  315.     // Parse feed data as it comes in
  316.     this._processor =
  317.         Cc["@mozilla.org/feed-processor;1"].
  318.         createInstance(Ci.nsIFeedProcessor);
  319.     this._processor.listener = this;
  320.     this._processor.parseAsync(null, channel.URI);
  321.     
  322.     this._processor.onStartRequest(request, context);
  323.   },
  324.   
  325.   /**
  326.    * See nsIRequestObserver.idl
  327.    */
  328.   onStopRequest: function FC_onStopReqeust(request, context, status) {
  329.     if (this._processor)
  330.       this._processor.onStopRequest(request, context, status);
  331.   },
  332.   
  333.   /**
  334.    * See nsISupports.idl
  335.    */
  336.   QueryInterface: function FC_QueryInterface(iid) {
  337.     if (iid.equals(Ci.nsIFeedResultListener) ||
  338.         iid.equals(Ci.nsIStreamConverter) ||
  339.         iid.equals(Ci.nsIStreamListener) ||
  340.         iid.equals(Ci.nsIRequestObserver)||
  341.         iid.equals(Ci.nsISupports))
  342.       return this;
  343.     throw Cr.NS_ERROR_NO_INTERFACE;
  344.   },
  345. };
  346.  
  347. var FeedConverterFactory = {
  348.   createInstance: function FS_createInstance(outer, iid) {
  349.     if (outer != null)
  350.       throw Cr.NS_ERROR_NO_AGGREGATION;
  351.     return new FeedConverter().QueryInterface(iid);
  352.   },
  353.  
  354.   QueryInterface: function FS_QueryInterface(iid) {
  355.     if (iid.equals(Ci.nsIFactory) ||
  356.         iid.equals(Ci.nsISupports))
  357.       return this;
  358.     throw Cr.NS_ERROR_NO_INTERFACE;
  359.   },
  360. };
  361.  
  362. /**
  363.  * Keeps parsed FeedResults around for use elsewhere in the UI after the stream
  364.  * converter completes. 
  365.  */
  366. var FeedResultService = {
  367.   
  368.   /**
  369.    * A URI spec -> [nsIFeedResult] hash. We have to keep a list as the
  370.    * value in case the same URI is requested concurrently.
  371.    */
  372.   _results: { },
  373.   
  374.   /**
  375.    * See nsIFeedResultService.idl
  376.    */
  377.   forcePreviewPage: false,
  378.   
  379.   /**
  380.    * See nsIFeedResultService.idl
  381.    */
  382.   addToClientReader: function FRS_addToClientReader(spec, title, subtitle, feedType) {
  383.     var prefs =   
  384.         Cc["@mozilla.org/preferences-service;1"].
  385.         getService(Ci.nsIPrefBranch);
  386.  
  387.     var handler = safeGetCharPref(getPrefActionForType(feedType), "bookmarks");
  388.     if (handler == "ask" || handler == "reader")
  389.       handler = safeGetCharPref(getPrefReaderForType(feedType), "bookmarks");
  390.  
  391.     switch (handler) {
  392.     case "client":
  393.       var clientApp = prefs.getComplexValue(getPrefAppForType(feedType), Ci.nsILocalFile);
  394.  
  395.       // For the benefit of applications that might know how to deal with more
  396.       // URLs than just feeds, send feed: URLs in the following format:
  397.       //
  398.       // http urls: replace scheme with feed, e.g.
  399.       // http://foo.com/index.rdf -> feed://foo.com/index.rdf
  400.       // other urls: prepend feed: scheme, e.g.
  401.       // https://foo.com/index.rdf -> feed:https://foo.com/index.rdf
  402.       var ios = 
  403.           Cc["@mozilla.org/network/io-service;1"].
  404.           getService(Ci.nsIIOService);
  405.       var feedURI = ios.newURI(spec, null, null);
  406.       if (feedURI.schemeIs("http")) {
  407.         feedURI.scheme = "feed";
  408.         spec = feedURI.spec;
  409.       }
  410.       else
  411.         spec = "feed:" + spec;
  412.  
  413.       // Retrieving the shell service might fail on some systems, most
  414.       // notably systems where GNOME is not installed.
  415.       try {
  416.         var ss =
  417.             Cc["@mozilla.org/browser/shell-service;1"].
  418.             getService(Ci.nsIShellService);
  419.         ss.openApplicationWithURI(clientApp, spec);
  420.       } catch(e) {
  421.         // If we couldn't use the shell service, fallback to using a
  422.         // nsIProcess instance
  423.         var p =
  424.             Cc["@mozilla.org/process/util;1"].
  425.             createInstance(Ci.nsIProcess);
  426.         p.init(clientApp);
  427.         p.run(false, [spec], 1);
  428.       }
  429.       break;
  430.  
  431.     default:
  432.       // "web" should have been handled elsewhere
  433.       LOG("unexpected handler: " + handler);
  434.       // fall through
  435.     case "bookmarks":
  436.       var wm = 
  437.           Cc["@mozilla.org/appshell/window-mediator;1"].
  438.           getService(Ci.nsIWindowMediator);
  439.       var topWindow = wm.getMostRecentWindow("navigator:browser");
  440.       topWindow.PlacesCommandHook.addLiveBookmark(spec, title, subtitle);
  441.       break;
  442.     }
  443.   },
  444.   
  445.   /**
  446.    * See nsIFeedResultService.idl
  447.    */
  448.   addFeedResult: function FRS_addFeedResult(feedResult) {
  449.     NS_ASSERT(feedResult.uri != null, "null URI!");
  450.     NS_ASSERT(feedResult.uri != null, "null feedResult!");
  451.     var spec = feedResult.uri.spec;
  452.     if(!this._results[spec])  
  453.       this._results[spec] = [];
  454.     this._results[spec].push(feedResult);
  455.   },
  456.   
  457.   /**
  458.    * See nsIFeedResultService.idl
  459.    */
  460.   getFeedResult: function RFS_getFeedResult(uri) {
  461.     NS_ASSERT(uri != null, "null URI!");
  462.     var resultList = this._results[uri.spec];
  463.     for (var i in resultList) {
  464.       if (resultList[i].uri == uri)
  465.         return resultList[i];
  466.     }
  467.     return null;
  468.   },
  469.   
  470.   /**
  471.    * See nsIFeedResultService.idl
  472.    */
  473.   removeFeedResult: function FRS_removeFeedResult(uri) {
  474.     NS_ASSERT(uri != null, "null URI!");
  475.     var resultList = this._results[uri.spec];
  476.     if (!resultList)
  477.       return;
  478.     var deletions = 0;
  479.     for (var i = 0; i < resultList.length; ++i) {
  480.       if (resultList[i].uri == uri) {
  481.         delete resultList[i];
  482.         ++deletions;
  483.       }
  484.     }
  485.     
  486.     // send the holes to the end
  487.     resultList.sort();
  488.     // and trim the list
  489.     resultList.splice(resultList.length - deletions, deletions);
  490.     if (resultList.length == 0)
  491.       delete this._results[uri.spec];
  492.   },
  493.  
  494.   createInstance: function FRS_createInstance(outer, iid) {
  495.     if (outer != null)
  496.       throw Cr.NS_ERROR_NO_AGGREGATION;
  497.     return this.QueryInterface(iid);
  498.   },
  499.   
  500.   QueryInterface: function FRS_QueryInterface(iid) {
  501.     if (iid.equals(Ci.nsIFeedResultService) ||
  502.         iid.equals(Ci.nsIFactory) ||
  503.         iid.equals(Ci.nsISupports))
  504.       return this;
  505.     throw Cr.NS_ERROR_NOT_IMPLEMENTED;
  506.   },
  507. };
  508.  
  509. /**
  510.  * A protocol handler that attempts to deal with the variant forms of feed:
  511.  * URIs that are actually either http or https.
  512.  */
  513. function FeedProtocolHandler(scheme) {
  514.   this._scheme = scheme;
  515.   var ios = 
  516.       Cc["@mozilla.org/network/io-service;1"].
  517.       getService(Ci.nsIIOService);
  518.   this._http = ios.getProtocolHandler("http");
  519. }
  520. FeedProtocolHandler.prototype = {
  521.   _scheme: "",
  522.   get scheme() {
  523.     return this._scheme;
  524.   },
  525.   
  526.   get protocolFlags() {
  527.     return this._http.protocolFlags;
  528.   },
  529.   
  530.   get defaultPort() {
  531.     return this._http.defaultPort;
  532.   },
  533.   
  534.   allowPort: function FPH_allowPort(port, scheme) {
  535.     return this._http.allowPort(port, scheme);
  536.   },
  537.   
  538.   newURI: function FPH_newURI(spec, originalCharset, baseURI) {
  539.     // See bug 408599 - feed URIs can be either standard URLs of the form
  540.     // feed://example.com, in which case the real protocol is http, or nested
  541.     // URIs of the form feed:realscheme:. When realscheme is either http or
  542.     // https, we deal with the way that creates a standard URL with the
  543.     // realscheme as the host by unmangling in newChannel; for others, we fail
  544.     // rather than let it wind up loading something like www.realscheme.com//foo
  545.  
  546.     const feedSlashes = "feed://";
  547.     const feedHttpSlashes = "feed:http://";
  548.     const feedHttpsSlashes = "feed:https://";
  549.     const NS_ERROR_MALFORMED_URI = 0x804B000A;
  550.  
  551.     if (spec.substr(0, feedSlashes.length) != feedSlashes &&
  552.         spec.substr(0, feedHttpSlashes.length) != feedHttpSlashes &&
  553.         spec.substr(0, feedHttpsSlashes.length) != feedHttpsSlashes)
  554.       throw NS_ERROR_MALFORMED_URI;
  555.  
  556.     var uri = 
  557.         Cc["@mozilla.org/network/standard-url;1"].
  558.         createInstance(Ci.nsIStandardURL);
  559.     uri.init(Ci.nsIStandardURL.URLTYPE_STANDARD, 80, spec, originalCharset,
  560.              baseURI);
  561.     return uri;
  562.   },
  563.   
  564.   newChannel: function FPH_newChannel(aUri) {
  565.     var ios = 
  566.         Cc["@mozilla.org/network/io-service;1"].
  567.         getService(Ci.nsIIOService);
  568.     // feed: URIs either start feed://, in which case the real scheme is http:
  569.     // or feed:http(s)://, (which by now we've changed to feed://realscheme//)
  570.     var feedSpec = aUri.spec;
  571.     const httpsChunk = "feed://https//";
  572.     const httpChunk = "feed://http//";
  573.     if (feedSpec.substr(0, httpsChunk.length) == httpsChunk)
  574.       feedSpec = "https://" + feedSpec.substr(httpsChunk.length);
  575.     else if (feedSpec.substr(0, httpChunk.length) == httpChunk)
  576.       feedSpec = "http://" + feedSpec.substr(httpChunk.length);
  577.     else
  578.       feedSpec = feedSpec.replace(/^feed/, "http");
  579.  
  580.     var uri = ios.newURI(feedSpec, aUri.originCharset, null);
  581.     var channel =
  582.       ios.newChannelFromURI(uri, null).QueryInterface(Ci.nsIHttpChannel);
  583.     // Set this so we know this is supposed to be a feed
  584.     channel.setRequestHeader("X-Moz-Is-Feed", "1", false);
  585.     channel.originalURI = aUri;
  586.     return channel;
  587.   },
  588.   
  589.   QueryInterface: function FPH_QueryInterface(iid) {
  590.     if (iid.equals(Ci.nsIProtocolHandler) ||
  591.         iid.equals(Ci.nsISupports))
  592.       return this;
  593.     throw Cr.NS_ERROR_NO_INTERFACE;
  594.   }  
  595. };
  596.  
  597. var Module = {
  598.   QueryInterface: function M_QueryInterface(iid) {
  599.     if (iid.equals(Ci.nsIModule) ||
  600.         iid.equals(Ci.nsISupports))
  601.       return this;
  602.     throw Cr.NS_ERROR_NO_INTERFACE;
  603.   },
  604.   
  605.   getClassObject: function M_getClassObject(cm, cid, iid) {
  606.     if (!iid.equals(Ci.nsIFactory))
  607.       throw Cr.NS_ERROR_NOT_IMPLEMENTED;
  608.     
  609.     if (cid.equals(FS_CLASSID))
  610.       return FeedResultService;
  611.     if (cid.equals(FPH_CLASSID))
  612.       return new GenericComponentFactory(FeedProtocolHandler, "feed");
  613.     if (cid.equals(PCPH_CLASSID))
  614.       return new GenericComponentFactory(FeedProtocolHandler, "pcast");
  615.     if (cid.equals(FC_CLASSID))
  616.       return new GenericComponentFactory(FeedConverter);
  617.       
  618.     throw Cr.NS_ERROR_NO_INTERFACE;
  619.   },
  620.   
  621.   registerSelf: function M_registerSelf(cm, file, location, type) {
  622.     var cr = cm.QueryInterface(Ci.nsIComponentRegistrar);
  623.     
  624.     cr.registerFactoryLocation(FS_CLASSID, FS_CLASSNAME, FS_CONTRACTID,
  625.                                file, location, type);
  626.     cr.registerFactoryLocation(FPH_CLASSID, FPH_CLASSNAME, FPH_CONTRACTID,
  627.                                file, location, type);
  628.     cr.registerFactoryLocation(PCPH_CLASSID, PCPH_CLASSNAME, PCPH_CONTRACTID,
  629.                                file, location, type);
  630.  
  631.     // The feed converter is always attached, since parsing must be done to 
  632.     // determine whether or not auto-handling can occur. 
  633.     const converterPrefix = "@mozilla.org/streamconv;1?from=";
  634.     var converterContractID = 
  635.         converterPrefix + TYPE_MAYBE_FEED + "&to=" + TYPE_ANY;
  636.     cr.registerFactoryLocation(FC_CLASSID, FC_CLASSNAME, converterContractID,
  637.                                file, location, type);
  638.  
  639.     converterContractID = 
  640.         converterPrefix + TYPE_MAYBE_VIDEO_FEED + "&to=" + TYPE_ANY;
  641.     cr.registerFactoryLocation(FC_CLASSID, FC_CLASSNAME, converterContractID,
  642.                                file, location, type);
  643.  
  644.     converterContractID = 
  645.         converterPrefix + TYPE_MAYBE_AUDIO_FEED + "&to=" + TYPE_ANY;
  646.     cr.registerFactoryLocation(FC_CLASSID, FC_CLASSNAME, converterContractID,
  647.                                file, location, type);
  648.     },
  649.   
  650.   unregisterSelf: function M_unregisterSelf(cm, location, type) {
  651.     var cr = cm.QueryInterface(Ci.nsIComponentRegistrar);
  652.     cr.unregisterFactoryLocation(FPH_CLASSID, location);
  653.     cr.unregisterFactoryLocation(PCPH_CLASSID, location);
  654.   },
  655.   
  656.   canUnload: function M_canUnload(cm) {
  657.     return true;
  658.   }
  659. };
  660.  
  661. function NSGetModule(cm, file) {
  662.   return Module;
  663. }
  664.  
  665. //@line 44 "/build/buildd/firefox-3.5-3.5.5+nobinonly/build-tree/mozilla/toolkit/content/debug.js"
  666.  
  667. var EXPORTED_SYMBOLS = ["NS_ASSERT"];
  668.  
  669. var gTraceOnAssert = true;
  670.  
  671. /**
  672.  * This function provides a simple assertion function for JavaScript.
  673.  * If the condition is true, this function will do nothing.  If the
  674.  * condition is false, then the message will be printed to the console
  675.  * and an alert will appear showing a stack trace, so that the (alpha
  676.  * or nightly) user can file a bug containing it.  For future enhancements, 
  677.  * see bugs 330077 and 330078.
  678.  *
  679.  * To suppress the dialogs, you can run with the environment variable
  680.  * XUL_ASSERT_PROMPT set to 0 (if unset, this defaults to 1).
  681.  *
  682.  * @param condition represents the condition that we're asserting to be
  683.  *                  true when we call this function--should be
  684.  *                  something that can be evaluated as a boolean.
  685.  * @param message   a string to be displayed upon failure of the assertion
  686.  */
  687.  
  688. function NS_ASSERT(condition, message) {
  689.   if (condition)
  690.     return;
  691.  
  692.   var releaseBuild = true;
  693.   var defB = Components.classes["@mozilla.org/preferences-service;1"]
  694.                        .getService(Components.interfaces.nsIPrefService)
  695.                        .getDefaultBranch(null);
  696.   try {
  697.     switch (defB.getCharPref("app.update.channel")) {
  698.       case "nightly":
  699.       case "beta":
  700.       case "default":
  701.         releaseBuild = false;
  702.     }
  703.   } catch(ex) {}
  704.  
  705.   var caller = arguments.callee.caller;
  706.   var assertionText = "ASSERT: " + message + "\n";
  707.  
  708.   if (releaseBuild) {
  709.     // Just report the error to the console
  710.     Components.utils.reportError(assertionText);
  711.     return;
  712.   }
  713.  
  714.   // Otherwise, dump to stdout and launch an assertion failure dialog
  715.   dump(assertionText);
  716.  
  717.   var stackText = "";
  718.   if (gTraceOnAssert) {
  719.     stackText = "Stack Trace: \n";
  720.     var count = 0;
  721.     while (caller) {
  722.       stackText += count++ + ":" + caller.name + "(";
  723.       for (var i = 0; i < caller.arguments.length; ++i) {
  724.         var arg = caller.arguments[i];
  725.         stackText += arg;
  726.         if (i < caller.arguments.length - 1)
  727.           stackText += ",";
  728.       }
  729.       stackText += ")\n";
  730.       caller = caller.arguments.callee.caller;
  731.     }
  732.   }
  733.  
  734.   var environment = Components.classes["@mozilla.org/process/environment;1"].
  735.                     getService(Components.interfaces.nsIEnvironment);
  736.   if (environment.exists("XUL_ASSERT_PROMPT") &&
  737.       !parseInt(environment.get("XUL_ASSERT_PROMPT")))
  738.     return;
  739.  
  740.   var source = null;
  741.   if (this.window)
  742.     source = this.window;
  743.   var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
  744.            getService(Components.interfaces.nsIPromptService);
  745.   ps.alert(source, "Assertion Failed", assertionText + stackText);
  746. }
  747. //@line 37 "/build/buildd/firefox-3.5-3.5.5+nobinonly/build-tree/mozilla/browser/components/feeds/src/GenericFactory.js"
  748.  
  749. /**
  750.  * An object implementing nsIFactory that can construct other objects upon
  751.  * createInstance, passing a set of parameters to that object's constructor.
  752.  */
  753. function GenericComponentFactory(ctor, params) {
  754.   this._ctor = ctor;
  755.   this._params = params;
  756. }
  757. GenericComponentFactory.prototype = {
  758.   _ctor: null,
  759.   _params: null,
  760.   
  761.   createInstance: function GCF_createInstance(outer, iid) {
  762.     if (outer != null)
  763.       throw Cr.NS_ERROR_NO_AGGREGATION;
  764.     return (new this._ctor(this._params)).QueryInterface(iid);
  765.   },
  766.   
  767.   QueryInterface: function GCF_QueryInterface(iid) {
  768.     if (iid.equals(Ci.nsIFactory) ||
  769.         iid.equals(Ci.nsISupports)) 
  770.       return this;
  771.     throw Cr.NS_ERROR_NO_INTERFACE;
  772.   }
  773. };
  774.  
  775.